package com.leyou.item.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.leyou.common.pojo.PageResult;
import com.leyou.item.bo.SpuBo;
import com.leyou.item.mapper.*;
import com.leyou.item.pojo.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class GoodsService {

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private SpuDetailMapper spuDetailMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;


    public PageResult<SpuBo> querySpuByPage(Integer page, Integer rows, String saleable, String key) {
        // 开启分页助手
        PageHelper.startPage(page, rows);
        // 创建查询条件
        Example example = new Example(Spu.class);
        // 查询条件的构建工具
        Example.Criteria criteria = example.createCriteria();
        // 是否进行模糊查询
        if (StringUtils.isNotBlank(key)) {
            criteria.andLike("title", "%" + key + "%");
        }
        if (saleable != null) {
            criteria.andEqualTo("saleable", saleable);
        }
        // select * from tb_spu where title like '%key%' and saleable = false
        List<Spu> spuList = spuMapper.selectByExample(example);
        Page<Spu> spuPage = (Page<Spu>) spuList;

        List<SpuBo> spuBos = new ArrayList<>();
        for (Spu spu : spuList) {
            SpuBo spuBo = new SpuBo();
            // 性拷贝
            BeanUtils.copyProperties(spu,spuBo);
            // 根据spu的商品分类的Id，查询商品分类的名称
            List<String> names = categoryService.queryNamesByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));
            spuBo.setCname(StringUtils.join(names,"/"));
            Brand brand = brandMapper.selectByPrimaryKey(spu.getBrandId());
            spuBo.setBname(brand.getName());
            spuBos.add(spuBo);
        }
        return new PageResult<>(spuPage.getTotal(), new Long(spuPage.getPages()), spuBos);
    }


    @Transactional
    public void saveGoods(SpuBo spuBo) {
        //商品保存
        //缺失了4个属性
        spuBo.setSaleable(true);
        spuBo.setValid(true);
        spuBo.setCreateTime(new Date());
        spuBo.setLastUpdateTime(spuBo.getCreateTime());
        //直接保存spu并回显id
        spuMapper.insertSelective(spuBo);

        //保存spuDetail,由于缺失spuId，所以要加入spuId
        SpuDetail spuDetail = spuBo.getSpuDetail();
        spuDetail.setSpuId(spuBo.getId());
        spuDetailMapper.insertSelective(spuDetail);

        //保存sku
        List<Sku> skus = spuBo.getSkus();
        saveSkus(spuBo, skus);
        sendMessage(spuBo.getId(), "insert");
    }

    private void saveSkus(SpuBo spuBo, List<Sku> skus) {
        //迭代sku集合保存
        skus.forEach(sku -> {
            sku.setSpuId(spuBo.getId());
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(sku.getCreateTime());
            //保存sku并回显id
            skuMapper.insertSelective(sku);
            //同时保存库存
            Stock stock = new Stock();
            stock.setSkuId(sku.getId());
            stock.setStock(sku.getStock());
            //保存库存
            stockMapper.insertSelective(stock);
        });
    }

    public SpuDetail querySpuDetailBySpuId(Long spuId) {
        return spuDetailMapper.selectByPrimaryKey(spuId);
    }

    public List<Sku> querySkuBySpuId(Long spuId) {
        Sku record = new Sku();
        record.setSpuId(spuId);
        List<Sku> skus = skuMapper.select(record);
        //同时要查询每个sku的库存
        skus.forEach(sku -> {
            //sku的id就是库存stock的主键
            sku.setStock(stockMapper.selectByPrimaryKey(sku.getId()).getStock());
        });
        return skus;
    }

    @Transactional
    public void updateGoods(SpuBo spuBo) {
        //spu，spuDetail可以直接更新
        spuBo.setLastUpdateTime(new Date());
        spuMapper.updateByPrimaryKeySelective(spuBo);
        spuDetailMapper.updateByPrimaryKeySelective(spuBo.getSpuDetail());
        //先删除当前spu对应的所有的sku，然后重新添加
        //先查，再根据查到的结果删除
        Sku record = new Sku();
        record.setSpuId(spuBo.getId());
        //从数据库中查询到的skus
        List<Sku> skus = skuMapper.select(record);
        //根据sku信息，删除对应数据库中的信息
        //删除库存数据
        if(!CollectionUtils.isEmpty(skus)){
            List<Long> ids = skus.stream().map(Sku::getId).collect(Collectors.toList());
            stockMapper.deleteByIdList(ids);
            skuMapper.delete(record);
        }
        //循环添加sku
        saveSkus(spuBo, spuBo.getSkus());
        sendMessage(spuBo.getId(), "update");
    }

    public Spu querySpuById(Long spuId) {
        return spuMapper.selectByPrimaryKey(spuId);
    }

    /**
     *
     * 发送消息的方法，id就是spuId，type就是操作类型（增删改查）
     * @param id
     * @param type
     */
    private void sendMessage(Long id, String type) {
        // 发送消息
        amqpTemplate.convertAndSend("item." + type, id);
    }
}
